<template>
    <el-dialog v-model="dialogVisible" title="Pipeline列表" width="70%" :before-close="handleClose"
        class="pipeline-dialog">
        <div class="pipeline-panel">
            <div class="pipeline-list">
                <el-scrollbar>
                    <ul>
                        <li v-for="(pipeline, index) in pipelines" :key="pipeline.name"
                            @click="selectPipeline(pipeline, index)" :class="{ active: selectedIndex === index }">
                            {{ pipeline.name }}
                        </li>
                    </ul>
                </el-scrollbar>
            </div>
            <div class="pipeline-details">
                <el-tabs v-model="activeTab" type="card" @tab-change="handleTabChange">
                    <el-tab-pane label="整体介绍" name="description" class="desc-zh-tab">
                        <div class="tab-content">
                            <p>{{ selectedPipeline?.['desc-zh'] || '无描述' }}</p>
                        </div>
                    </el-tab-pane>
                    <el-tab-pane label="推理结构" name="structure" class="structure-tab">
                        <div class="tab-content">
                            <canvas class="pipeline-canvas"></canvas>
                        </div>
                    </el-tab-pane>
                    <el-tab-pane label="输入参数" name="parameters" class="input-tab">
                        <div class="tab-content">
                            <PipeInput ref="input_panel"> </PipeInput>
                        </div>
                    </el-tab-pane>
                </el-tabs>
            </div>
        </div>
        <template #footer>
            <el-button @click="handleClose">取消</el-button>
            <el-button type="primary" @click="handleConfirm">确定</el-button>
        </template>
    </el-dialog>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick, getCurrentInstance, inject } from 'vue';
import API from '@/js/api';
let vueApp = inject('vueApp');
const { proxy } = getCurrentInstance();
import { PipelineDrawer } from '@/js/utils/pipelineDrawer';
import PipeInput from './PipeInput.vue';

// 返回获取的输入信息
const emit = defineEmits(['dlgConfirm']);

// 外部调用传入的参数
const invoker_params = ref(null);

// 定义pipeline各种变量
const dialogVisible = ref(false);
const pipelines = ref([]);
const selectedPipeline = ref(null);
const selectedIndex = ref(0);
const activeTab = ref('description');
const pipelineConfig = ref(null);
const pipelineDrawer = ref(null);

// 获取 canvas 元素
const getCanvas = () => document.querySelector('.pipeline-canvas');

// 设置 Canvas 宽高
const setCanvasSize = async () => {
    await nextTick();
    const canvas = getCanvas();
    if (canvas) {
        const rect = canvas.getBoundingClientRect();
        canvas.width = rect.width;
        canvas.height = rect.height;
    }
};

// 初始化或更新 PipelineDrawer
const initOrUpdatePipelineDrawer = () => {
    const canvas = getCanvas();
    if (!canvas) return;

    if (pipelineDrawer.value) {
        pipelineDrawer.value.pipelineConfig = pipelineConfig.value;
        pipelineDrawer.value.resetView();
    } else {
        pipelineDrawer.value = new PipelineDrawer(canvas, pipelineConfig.value);
    }
    pipelineDrawer.value.draw();
};

// 获取 Pipeline 列表
const fetchPipelines = async (invoke_from) => {
    try {
        let result = await API.invoke('GetPipelines', {
            invoke_from: invoke_from
        });
        // console.log('GetPipelines result = ', result);
        if (result.code === 0) {
            pipelines.value = result.msg;
            if (pipelines.value.length > 0) {
                selectPipeline(pipelines.value[0], 0);
            }
        } else {
            pipelines.value = [];
        }
    } catch (error) {
        ElMessage.error('Failed to fetch pipelines');
    }
};

// 选择 Pipeline
const selectPipeline = async (pipeline, index) => {
    selectedPipeline.value = pipeline;
    selectedIndex.value = index;
    try {
        let result = await API.invoke('GetPipeConfig', { name: pipeline.name });
        if (result.code === 0) {
            pipelineConfig.value = result.msg;

            if (activeTab.value === 'structure') {
                await setCanvasSize();
                initOrUpdatePipelineDrawer();
            } else if (activeTab.value === 'parameters') {
                proxy.$refs.input_panel && proxy.$refs.input_panel.setInputs(result.msg.input, invoker_params.value.input_data);
            }
        } else {
            pipelineConfig.value = null;
            proxy.$refs.input_panel && proxy.$refs.input_panel.setInputs([], {});
        }
    } catch (error) {
        ElMessage.error('Failed to fetch pipeline config');
    }
};

// 关闭对话框
const handleClose = () => {
    vueApp.monitorKeyEvent(true);
    dialogVisible.value = false;
};

// 确认选择
const handleConfirm = () => {
    vueApp.monitorKeyEvent(true);
    // console.log('Selected Pipeline:', selectedPipeline.value);
    if (proxy.$refs.input_panel) {
        const inputs = proxy.$refs.input_panel.getInputs();
        // console.log(`inputs = `, inputs, `, invoker_params = `, invoker_params.value);
        emit('dlgConfirm', {
            pipeline: {
                name: selectedPipeline.value.name,
                config: selectedPipeline.value.config,
            },
            batch: invoker_params.value.batch,
            inputs: inputs
        });
    } else {
        ElMessage.error('Failed to get inputs');
    }
    dialogVisible.value = false;
};

// 显示对话框
const showDialog = async (params) => {
    // 关闭app其他控件对于键盘响应
    vueApp.monitorKeyEvent(false);

    // 设置调用pipeline输入的信息，主要是数据集（批量）和数据
    console.log('showDialog params = ', params);
    invoker_params.value = params;
    await fetchPipelines(params.invoke_from);

    // 打开对话框窗口
    dialogVisible.value = true;

    // 切换到参数面板
    activeTab.value = 'parameters';
};

// 切换标签页
const handleTabChange = async (tab) => {
    if (tab === 'structure' && pipelineConfig.value) {
        await setCanvasSize();
        initOrUpdatePipelineDrawer();
    } else if (tab === 'parameters' && pipelineConfig.value) {
        proxy.$refs.input_panel && proxy.$refs.input_panel.setInputs(pipelineConfig.value.input, invoker_params.value.input_data);
    }
};

// 监听窗口大小变化
const handleResize = async () => {
    await setCanvasSize();
    if (pipelineDrawer.value) {
        pipelineDrawer.value.draw();
    }
};

onMounted(async () => {
    window.addEventListener('resize', handleResize);
});

onUnmounted(() => {
    window.removeEventListener('resize', handleResize);
});

defineExpose({ showDialog });
</script>

<style scoped>
.pipeline-dialog {
    display: block;
}

.pipeline-panel {
    display: flex;
    background-color: #ffffff;
    width: 100%;
    height: 300px;
    border: 1px solid #cfcfcf;
    box-sizing: border-box;
}

.pipeline-list {
    width: 180px;
    padding: 10px;
    border-right: 1px solid #ebeef5;
    overflow-y: auto;
}

.pipeline-list ul {
    list-style-type: none;
    padding: 0;
    margin: 0;
}

.pipeline-list li {
    padding: 10px;
    cursor: pointer;
    border-bottom: 1px solid #ebeef5;
    transition: background-color 0.3s;
}

.pipeline-list li:hover {
    background-color: #f5f7fa;
}

.pipeline-list li.active {
    background-color: #e6f7ff;
    font-weight: bold;
}

.pipeline-details {
    flex: 1;
    padding: 3px;
    box-sizing: border-box;
    flex-direction: column;
}

.tab-content {
    flex: 1;
    height: 100%;
    box-sizing: border-box;
}

.tab-content h3 {
    margin-top: 0;
    margin-bottom: 10px;
}

.tab-content p {
    margin: 0;
}

.el-tabs {
    width: 100%;
    height: 100%;
}

.el-tabs__header {
    margin: 0px;
}

.desc-zh-tab {
    padding: 0px 10px;
}

.structure-tab {
    padding: 1px;
    width: 100%;
    height: 100%;
}

.input-tab {
    padding: 0px 10px;
}

.pipeline-canvas {
    width: 100%;
    height: 100%;
    border: 1px solid #ebeef5;
}

.el-dialog__footer {
    text-align: right;
}
</style>